package
{

    import com.bit101.components.PushButton;
    import com.bit101.components.TextArea;

    import flash.desktop.ClipboardFormats;
    import flash.desktop.NativeDragManager;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.NativeDragEvent;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.FileReference;
    import flash.net.SharedObject;
    import flash.utils.ByteArray;

    [SWF(width="500", height="400", backgroundColor="#ffffff", frameRate="24")]
    public class CECompress extends Sprite
    {
        private var mSaveBtn:PushButton;
        private var mLogTextArea:TextArea;
        private var mAllNeedCompressFileArray:Array;

        //记录Config信息
        private var configSaveData:SharedObject;


        private var mCurrentDragDropErrorInfo:String;

        public function CECompress()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            mAllNeedCompressFileArray = [];

            configSaveData = SharedObject.getLocal("CECompressConfig");

            initGUI();
            initDragDrop();

            refreshComressBtn();
            refreshDropFileList();
        }

        //=========================//
        //== GUI
        //=========================//

        private function initGUI():void
        {
            mSaveBtn = new PushButton(this, 0, 20, "Compress", onClickCompressBtn);
            mSaveBtn.x = (this.stage.stageWidth - mSaveBtn.width) / 2;
            mSaveBtn.enabled = false;

            mLogTextArea = new TextArea(this, 0, 50, "");
            mLogTextArea.width = this.stage.stageWidth;
            mLogTextArea.height = 350;
        }

        private function refreshDropFileList():void
        {
            if (mAllNeedCompressFileArray.length > 0)
            {
                var mLogString:String = "";
                mLogString += "====================\n";
                mLogString += "   目前列表中的文件:\n";
                mLogString += "====================\n";
                for each(var subFile:File in mAllNeedCompressFileArray)
                {
                    mLogString += subFile.name + "\n";
                }


                if (mCurrentDragDropErrorInfo != null)
                {
                    mLogString += "\n\n";
                    mLogString += "====================\n";
                    mLogString += "  ERROR || WARNING\n";
                    mLogString += "====================\n";
                    mLogString += mCurrentDragDropErrorInfo;
                }
                mLogTextArea.text = mLogString;

            }
            else
            {
                mLogTextArea.text = "将需要压缩的文件或文件夹拖拽到这里";
            }
        }

        private function refreshComressBtn():void
        {
            mSaveBtn.enabled = mAllNeedCompressFileArray.length > 0;
        }

        //========================//
        //==Drag Drop Handle
        //=========================//

        private function initDragDrop():void
        {
            this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, onFileDragIn);
            this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, onFileDrop);
        }

        private function onFileDragIn(e:NativeDragEvent):void
        {
            NativeDragManager.acceptDragDrop(this);
        }

        private function onFileDrop(e:NativeDragEvent):void
        {
            mCurrentDragDropErrorInfo = null;
            var allDropFiles:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;

            for each(var subDropFile:File in allDropFiles)
            {
                tryToPushFileToArray(subDropFile);
            }
            //刷新显示
            refreshDropFileList();
            refreshComressBtn();
        }

        /**
         * 尝试将某个文件添加到Array中
         */
        private function tryToPushFileToArray(_newFile:File):void
        {
            if (_newFile.isDirectory)
            {
                var subFileList:Array = _newFile.getDirectoryListing();
                for each(var subFile:File in subFileList)
                {
                    tryToPushFileToArray(subFile);
                }
            }
            //排除苹果的缓存文件
            else if (_newFile.name != ".DS_Store")
            {
                for each(var exitsFile:File in mAllNeedCompressFileArray)
                {
                    if (_newFile.name == exitsFile.name)
                    {
                        //已经存在了或者同名,不能添加
                        mCurrentDragDropErrorInfo += "[WARNING] 无法拖入文件: " + _newFile.name + " 因为和已有文件同名\n";
                        return;
                    }
                }
                mAllNeedCompressFileArray.push(_newFile);
            }
        }

        //==========================
        //==Compress
        //==========================
        private function onClickCompressBtn(e:Event):void
        {
            var compressByteArray:ByteArray = new ByteArray();
            var compressObj:Object = {};
            for each(var eachFile:File in mAllNeedCompressFileArray)
            {
                try
                {
                    var eachFileByteArray:ByteArray = new ByteArray();
                    var fileStrean:FileStream = new FileStream();
                    fileStrean.open(eachFile, FileMode.READ);
                    fileStrean.readBytes(eachFileByteArray);
                    compressObj[eachFile.name] = eachFileByteArray;
                    fileStrean.close();
                }
                catch (_e:Error)
                {
                    var errStr:String = "[错误] 中断\n 无法读取文件: " + eachFile.name + "\n";
                    mLogTextArea.text = errStr + _e.toString();
                }
            }

            compressByteArray.writeObject(compressObj);
            compressByteArray.compress();

            //从ShareObject中取得上次记录的文件名
            var fileName:String = configSaveData.data["lastSaveFileName"] == null ? "RAW.dat" : configSaveData.data["lastSaveFileName"];

            var saveFile:FileReference = new FileReference();
            saveFile.addEventListener(Event.COMPLETE, saveCompleteHandler);
            saveFile.addEventListener(IOErrorEvent.IO_ERROR, saveIOErrorHandler);
            saveFile.save(compressByteArray, fileName);
        }

        private function saveCompleteHandler(e:Event):void
        {
            var fileName:String = (e.target as FileReference).name;
            configSaveData.data["lastSaveFileName"] = fileName;
            configSaveData.flush();

            mAllNeedCompressFileArray.length = 0;
            mLogTextArea.text = "保存成功!\n\n关闭软件或继续使用";
            refreshComressBtn();
        }

        private function saveIOErrorHandler(e:Event):void
        {
            mLogTextArea.text = "[错误] 无法保存最终的压缩文件\n" + e.toString();
        }

    }
}
